#pragma once

//////////////////////////////////////////////////////////////////////////////
// Forward Declarations
//////////////////////////////////////////////////////////////////////////////
class TriEdge;
class TriVertex;

//////////////////////////////////////////////////////////////////////////////
// VertexCirculator
//
// Description:
//      Class to circulate around a vertex.
//      The behaviour varies depending whether models with boundaries
//      are allowed or not.
//
// Usage:
//      Instantiate an object by passing a pointer to a TriVertex.
//      Then start a loop with Start() and Advance() until Done() returns true.
//      Retrieve edge pointers with Get().
//      After Done() is set to true, it will return the last valid element.
//
// More:
//      We can check for long loops using an iteration counter and the valence
//      of the vertex 
//////////////////////////////////////////////////////////////////////////////

class VertexCirculator
{

protected:
   TriEdge *base;
   TriEdge *valid;
   TriEdge *now;
   bool done;
   bool CW;
   bool CCW;
   bool second;

#ifdef _DEBUG
   //This is only for checking long loops
   TriVertex *vertex;
   int iter;
#endif

public:
   //Constructors and destructors
   VertexCirculator(void)
   {
      SetNoBase();
   }

   VertexCirculator(const TriVertex* v)
   {
      SetBase(v);
   }

   ~VertexCirculator(void){}

   //Get Methods
   TriEdge* Get(void)
   {
      return valid;
   }

   bool HasBase(void);

   //Set Methods
   void SetBase(const TriVertex* v);

   void SetNoBase(void);

   //Control Methods
   void Start(void)
   {
      done=!HasBase();
      now=base;
      valid=base;
      second=false;
#ifdef _DEBUG
      iter=0;
#endif
   }

   bool IsDone(void)
   {
      return done;
   }

   virtual bool HitBoundary(void)=0;

   //Advance
   virtual void Advance(void)=0;

protected:
   //Advance
   bool AdvanceCW(void);

   bool AdvanceCCW(void);

};


//////////////////////////////////////////////////////////////////////////////
// CWVertexCirculator
//
// Description:
//      Class to circulate around a vertex in clockwise mode.
//////////////////////////////////////////////////////////////////////////////

class CWVertexCirculator : public VertexCirculator
{

public:
   //Constructors and destructors
   CWVertexCirculator(void)
   {
      CW=true;
      CCW=false;
   }

   CWVertexCirculator(const TriVertex* v) : VertexCirculator(v)
   {
      CW=true;
      CCW=false;
   }

   ~CWVertexCirculator(void){}

   //Control Methods
   bool HitBoundary(void)
   {
      return !CW;
   }

   //Advance
   void Advance(void);

};


//////////////////////////////////////////////////////////////////////////////
// CCWVertexCirculator
//
// Description:
//      Class to circulate around a vertex in counterclockwise mode.
//////////////////////////////////////////////////////////////////////////////

class CCWVertexCirculator : public VertexCirculator
{

public:
   //Constructors and destructors
   CCWVertexCirculator(void)
   {
      CW=false;
      CCW=true;
   }

   CCWVertexCirculator(const TriVertex* v) : VertexCirculator(v)
   {
      CW=false;
      CCW=true;
   }

   ~CCWVertexCirculator(void){}

   //Control Methods
   bool HitBoundary(void)
   {
      return !CCW;
   }

   //Advance
   void Advance(void);

};

